package com.learn.english.controller;

import com.learn.english.domain.R;
import com.learn.english.enums.ResultCode;
import com.learn.english.exception.BusinessException;
import com.learn.english.model.entity.UserMenu;
import com.learn.english.model.ro.MenuRo;
import com.learn.english.service.IMenuService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * @author TISNIW
 * @version 1.0
 * @date 2025/6/21 20:53
 * @desc 菜单管理控制器，提供目录树的完整CRUD操作
 */
@RestController
@RequestMapping("/menu")
public class MenuController {
    @Autowired
    private IMenuService menuService;
    
    /**
     * 根据角色ID获取菜单列表
     */
    @GetMapping("/get")
    public R<List<MenuRo>> getMenu(Integer roleId, Integer type, Integer pageId) {
        try {
            return R.ok(menuService.getMenu(roleId, type, pageId));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 获取所有菜单的树形结构
     */
    @GetMapping("/list")
    public R<List<UserMenu>> getMenuList(@RequestParam(required = false) String name,
                                       @RequestParam(required = false) Byte type,
                                       @RequestParam(required = false) Byte status) {
        try {
            return R.ok(menuService.getMenuTree(name, type, status));
        } catch (Exception e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 添加菜单
     */
    @PostMapping("/add")
    public R<String> addMenu(@RequestBody UserMenu menu, HttpServletRequest request){
        try {
            // 从请求中获取操作用户ID
            Integer operatorId = (Integer) request.getAttribute("userId");
            if (operatorId != null) {
                menu.setOperatorId(operatorId);
            }
            return R.ok(menuService.addMenu(menu));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 更新菜单
     */
    @PostMapping("/update")
    public R<String> updateMenu(@RequestBody UserMenu menu, HttpServletRequest request) {
        try {
            // 从请求中获取操作用户ID
            Integer operatorId = (Integer) request.getAttribute("userId");
            if (operatorId != null) {
                menu.setOperatorId(operatorId);
            }
            return R.ok(menuService.updateMenu(menu));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 删除菜单
     */
    @PostMapping("/delete/{id}")
    public R<String> deleteMenu(@PathVariable Integer id) {
        try {
            return R.ok(menuService.deleteMenu(id));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 批量删除菜单
     */
    @PostMapping("/batchDelete")
    public R<String> batchDeleteMenus(@RequestBody List<Integer> ids) {
        try {
            return R.ok(menuService.batchDeleteMenus(ids));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 更新菜单状态
     */
    @PostMapping("/updateStatus/{id}")
    public R<String> updateMenuStatus(@PathVariable Integer id, @RequestBody Map<String, Object> requestBody) {
        try {
            Byte status = requestBody.get("status") instanceof Number ? 
                ((Number) requestBody.get("status")).byteValue() : null;
            return R.ok(menuService.updateMenuStatus(id, status));
        } catch (IllegalArgumentException e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
    
    /**
     * 检查菜单是否有子菜单
     */
    @GetMapping("/hasChildren/{id}")
    public R<Boolean> hasChildren(@PathVariable Integer id) {
        try {
            return R.ok(menuService.hasChildren(id));
        } catch (Exception e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
}
